package com.pine.web.pineframework.controller;

import cn.hutool.core.lang.tree.Tree;
import com.pine.common.beans.ResultVo;
import com.pine.common.beans.pineframework.request.SysMenuQueryRequest;
import com.pine.common.beans.pineframework.request.SysMenuSaveOrUpdateRequest;
import com.pine.common.beans.pineframework.response.SysMenuQueryResponse;
import com.pine.common.beans.request.BatchIdRequest;
import com.pine.common.beans.request.IdRequest;
import com.pine.common.beans.response.DeleteResponse;
import com.pine.common.beans.response.DropDownTreeResponse;
import com.pine.common.systemlog.annotation.SysLog;
import com.pine.common.util.time.TimeUtil;
import com.pine.common.util.tree.TreeUtil;
import com.pine.dao.pineframework.constants.MenuTypeEnum;
import com.pine.dao.pineframework.constants.VisibleEnum;
import com.pine.dao.pineframework.entity.SysMenu;
import com.pine.manager.pineframework.trigger.SysMenuTriggerManager;
import com.pine.service.pineframework.SysMenuService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Optional;

/**
 * <p>
 * 系统菜单前端控制器
 * </p>
 *
 * @author pine manage
 * @since 2024-08-19
 */
@Tag(name = "系统菜单前端控制器")
@RestController
@RequestMapping("/sys/menu")
public class SysMenuController {

    @Resource
    private SysMenuService sysMenuService;

    /**
     * 查询菜单树形结构
     *
     * @param request 请求
     * @return 响应
     */
    @PostMapping(value = "/listTree")
    @Operation(summary = "查询菜单树形结构")
    @SysLog("查询菜单树形结构")
    public ResultVo<List<Tree<Long>>> listTree(@RequestBody @Valid SysMenuQueryRequest request) {
        List<SysMenuQueryResponse> queryResponses = sysMenuService.list(request);

        // 转换为树形结构
        List<Tree<Long>> trees = TreeUtil.convertLongIdTree(queryResponses, (map, resp) -> {
            map.put("menuType", resp.getMenuType());
            MenuTypeEnum menuTypeEnum = MenuTypeEnum.of(resp.getMenuType());
            Optional.ofNullable(menuTypeEnum).ifPresent(menuTypeEnum1 -> map.put("menuTypeDesc", menuTypeEnum1.getDesc()));
            map.put("routeName", resp.getRouteName());
            map.put("routePath", resp.getRoutePath());
            map.put("routeParams", resp.getRouteParams());
            map.put("redirect", resp.getRedirect());
            map.put("permission", resp.getPermission());
            map.put("visible", resp.getVisible());
            VisibleEnum visibleEnum = VisibleEnum.of(resp.getVisible());
            Optional.ofNullable(visibleEnum).ifPresent(visibleEnum1 -> map.put("visibleDesc", visibleEnum1.getDesc()));
            map.put("icon", resp.getIcon());
            map.put("sort", resp.getSort());
            map.put("component", resp.getComponent());
            map.put("createTime", TimeUtil.defaultFormat(resp.getCreateTime()));
            map.put("updateTime", TimeUtil.defaultFormat(resp.getUpdateTime()));
        });
        return ResultVo.success(trees);
    }

    /**
     * 下拉菜单树形结构
     *
     * @return 响应
     */
    @PostMapping(value = "/dropDownTree")
    @Operation(summary = "下拉菜单树形结构")
    @SysLog("下拉菜单树形结构")
    public ResultVo<List<Tree<Long>>> dropDownTree() {
        // 查询所有启用中的菜单信息
        List<DropDownTreeResponse<Long>> dropDownTreeResponses = sysMenuService.dropDownTree();

        // 转换为树形结构
        List<Tree<Long>> trees = TreeUtil.convertLongIdTree(dropDownTreeResponses, null);
        return ResultVo.success(trees);
    }

    /**
     * 删除
     *
     * @param request 请求
     * @return 响应
     */
    @PostMapping(value = "/delete")
    @Operation(summary = "删除信息")
    @SysLog("删除信息")
    public ResultVo<DeleteResponse> delete(@RequestBody @Valid IdRequest<Long> request) {
        // 获取菜单和子菜单
        List<SysMenu> sysMenuList = sysMenuService.listMenuAndChild(request.getId());
        List<Long> menuIds = sysMenuList.stream().map(SysMenu::getId).distinct().toList();

        // 批量删除
        BatchIdRequest<Long> batchIdRequest = new BatchIdRequest<>();
        batchIdRequest.setIds(menuIds);
        return ResultVo.success(SysMenuTriggerManager.delete(batchIdRequest));
    }

    /**
     * 新增
     *
     * @param request 请求
     * @return 响应
     */
    @PostMapping(value = "/save")
    @Operation(summary = "新增信息")
    @SysLog("新增信息")
    public ResultVo<Boolean> save(@RequestBody @Valid SysMenuSaveOrUpdateRequest request) {
        Boolean triggerResult = SysMenuTriggerManager.saveOrUpdate(request);
        return ResultVo.success(triggerResult);
    }

    /**
     * 更新
     *
     * @param request 请求
     * @return 响应
     */
    @PostMapping(value = "/update")
    @Operation(summary = "更新信息")
    @SysLog("更新信息")
    public ResultVo<Boolean> update(@RequestBody @Valid SysMenuSaveOrUpdateRequest request) {
        Boolean triggerResult = SysMenuTriggerManager.saveOrUpdate(request);
        return ResultVo.success(triggerResult);
    }
}
